#include <stdio.h>
#include <stdlib.h>

#include "fcqueue.h"

//=============================================================================
//=============================================================================
fcqueue_t *fcqueue_new (void)
{
  fcqueue_t *q = NULL;

  if ((q = malloc (sizeof (fcqueue_t))) == NULL) return (NULL);
  if ((q->queue = new_list ()) == NULL)
    {
      free (q);
      return (NULL);
    }
  if (pthread_mutex_init (&q->lock, NULL) < 0)
    {
      free_list (q->queue);
      free (q);
      return (NULL);
    }
  return (q);
}

//=============================================================================
//=============================================================================
void fcqueue_free (fcqueue_t *q)
{
  pthread_mutex_destroy (q&->lock);
  list_iterate (q->queue, (void (*)(void *))file_change_free);
  free_list (q->queue);
  free (q);
}

//=============================================================================
//=============================================================================
void fcqueue_push (fcqueue_t *q, file_change_t *data)
{
  pthread_mutex_lock (&q->lock);
  list_insert (q->queue, q->queue->length, data);
  pthread_mutex_unlock (&q->lock);
}

//=============================================================================
//=============================================================================
file_change_t *fcqueue_pop (fcqueue_t *q)
{
  void *retval = NULL;
  if (q->queue->length <= 0) return (NULL);
  pthread_mutex_lock (&q->lock);
  retval = list_remove (q->queue, 0);
  pthread_mutex_unlock (&q->lock);

  return (retval);
}

//=============================================================================
//=============================================================================
int fcqueue_has_next (fcqueue_t *q)
{
  int num = 0;
  pthread_mutex_lock (&q->lock);
  num = q->queue->length;
  pthread_mutex_unlock (&q->lock);
  return (num);
}



//=============================================================================
// File change event constructor.
//=============================================================================
file_change_t *file_change_new (file_change_code event, char *root, char *path)
{
  file_change_t *retval = NULL;

  if ((retval = malloc (sizeof (file_change_t))) == NULL) return (NULL);
  if ((retval->root = strdup (root)) == NULL)
    {
      free (retval);
      return (NULL);
    }
  if ((retval->path = strdup (path)) == NULL)
    {
      free (retval->root);
      free (retval);
      return (NULL);
    }
  retval->event = event;
  return (retval);
}

//=============================================================================
//=============================================================================
void file_change_free (file_change_t *fc)
{
  free (fc->root);
  free (fc->path);
  free (fc);
}
